#include "GameEngine/Character.hpp"

#include "util/Text.h"

/**
 * Init a new character with defalut value
 */
Character::Character(Map* p_map) :
	m_DirectionVertical(None), 		Moveable(p_map),			m_state(Character::WAITING),
	m_DirectionHorizontal(None), 	m_life(100), 				m_kill(0),
	m_death(0),						m_id(0)
{
	this->m_name 		= "";
	this->m_speed 		= DefaultValue::PLAYER_SPEED;
	this->m_width 		= DefaultValue::PLAYER_SIZE;
	this->m_height 		= DefaultValue::PLAYER_SIZE;
	this->m_timerShoot 	= DefaultValue::PLAYER_SHOOT_TIMER;

	//TODO : System de respawn not implemented
	this->m_position->x = 80;
	this->m_position->y = 80;
}

Character::~Character()
{
}
/**
 * Move the player to the new position with direction and speed
 */
void Character::Move(float p_newTime)
{
	// decrement timer
	if(this->m_timerShoot > 0)
	{
		this->m_timerShoot -= p_newTime;
	}

	//Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run", Text::float2string(p_newTime));

	// TODO lvl3 : corect bug diagonale (move faster)

	sf::Vector2f l_newPosition = this->Getposition();
	sf::Vector2f l_oldPosition = l_newPosition;
	float l_speed = this->Getspeed();

    //Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run Before X", Text::float2string(l_oldPosition.x));
    //Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run Before Y", Text::float2string(l_oldPosition.y));

	//Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run value", (m_DirectionVertical==Character::North)?"nord":"autre");
	//Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run value", (m_DirectionVertical==Character::South)?"sud":"autre");

    if(this->m_DirectionVertical == Character::North)
    {
        l_newPosition.y = l_newPosition.y - l_speed * p_newTime;
    }
    else if (this->m_DirectionVertical == Character::South)
    {
    	l_newPosition.y = l_newPosition.y + l_speed * p_newTime;
    }

    if(this->m_DirectionHorizontal == Character::East)
    {
    	l_newPosition.x = l_newPosition.x + l_speed * p_newTime;
    }
    else if (this->m_DirectionHorizontal == Character::West)
    {
    	l_newPosition.x = l_newPosition.x - l_speed * p_newTime;
    }

    //Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run X", Text::float2string(l_oldPosition.x));
    //Debug::printTrace(Debug::information, "GameEngine/GameEngine.Run Y", Text::float2string(l_oldPosition.y));

    // if direction is null don't request to change the position
    if(this->m_DirectionHorizontal != Character::None || this->m_DirectionVertical != Character::None)
    {
    	this->Setposition(sf::Vector2f(l_newPosition.x, l_oldPosition.y));
    	l_oldPosition = this->Getposition();
    	this->Setposition(sf::Vector2f(l_oldPosition.x, l_newPosition.y));
    }
}
/**
 * decrease the life of the character and set status DEAD if life < 0
 * return true player is dead
 */
bool Character::TakeDamage(const float p_damage)
{
	m_life -= p_damage;

	if(m_life <= 0)
	{
		this->m_state = Character::DEAD;
		return true;
	}
	return false;
}
/**
 * The Player spawn if he can
 * if the player spawn, return true
 */
bool Character::Spawn()
{
	float l_positionX, l_positionY;

	sf::Vector2f l_oldPosition = this->Getposition();

	while(l_oldPosition == this->Getposition())
	{
		l_positionX = std::rand() % (this->m_map->GetMapWidth()  * this->m_map->GetTileSize());
		l_positionY = std::rand() % (this->m_map->GetMapHeight() * this->m_map->GetTileSize());

		this->Setposition(sf::Vector2f(l_positionX, l_positionY));
	}
	this->Spawn(sf::Vector2f(l_positionX, l_positionY));
	return true;
}
/**
 * Spawn the player in the new position and reload the life
 */
void Character::Spawn(sf::Vector2f p_position)
{
	this->m_state = Character::ALIVE;
	this->m_life = DefaultValue::PLAYER_LIFE;
	this->Setposition(p_position);
}
/**
 * Check if the player can shoot (State + timer)
 */
bool Character::CanShoot()
{
	if(this->m_timerShoot < 0 && this->m_state == Character::ALIVE)
	{
		return true;
	}
	return false;
}
/**
 * player shoot and restart his timer
 */
void Character::Shoot()
{
	this->m_timerShoot 	= DefaultValue::PLAYER_SHOOT_TIMER;
}
